package cn.wolfcode.luowowo.redis.RedisService.impl;

import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.redis.RedisService.IStrategyStatisVORedisService;
import cn.wolfcode.luowowo.redis.util.RedisKeys;
import cn.wolfcode.luowowo.redis.vo.StrategyStatisVO;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatisVORedisServiceImpl implements IStrategyStatisVORedisService {
    //注入redis的操作
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //注入攻略服务接口
    @Autowired
    private IStrategyService strategyService;

    @Override
    public StrategyStatisVO getStatisVo(String sid) {
        //创建vo对象key
        String key = RedisKeys.STATISVO.json(sid);
        StrategyStatisVO vo = null;
        //判断redis缓存中key是否存在
        if (stringRedisTemplate.hasKey(key)) {
            //如果存在，根据key获取对象
            String voStr = stringRedisTemplate.opsForValue().get(key);
            //因为从redis缓存中获取到的是json格式的字符串对象所以要将对象转回vo对象
            vo = JSON.parseObject(voStr, StrategyStatisVO.class);
        } else {
            //如果不在，就创建一个vo对象，并初始化
            vo = new StrategyStatisVO();
            //根据攻略id获取攻略
            Strategy strategy = strategyService.get(sid);
            //将攻略理的数据复制到攻略redis中统计数据
            BeanUtils.copyProperties(strategy, vo);
            vo.setStrategyId(strategy.getId());
        }
        return vo;
    }

    @Override
    public void setStatisVo(StrategyStatisVO vo) {
        String key = RedisKeys.STATISVO.json(vo.getStrategyId());
        //然后更新或者保存
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(vo));

    }

    //阅读数加一
    @Override
    public void viewnumIncrease(String id, int i) {
        //判断redis缓存中key是否存在
        StrategyStatisVO vo = this.getStatisVo(id);
        //再将vo对象里的viewnum加一
        vo.setViewnum(vo.getViewnum() + i);
        //更新
        this.setStatisVo(vo);
    }

    @Override
    public void addCommentVo(String strategyId) {
        //判断redis缓存中key是否存在
        StrategyStatisVO statisVo = this.getStatisVo(strategyId);
        //将评论数加一
        statisVo.setReplynum(statisVo.getReplynum() + 1);
        //更新
        this.setStatisVo(statisVo);


    }

    //收藏
    @Override
    public boolean favor(String sid, String uid) {


//        1.2先创建key
        String key = RedisKeys.FAVOR.json(uid);
//        1.3创建一个空数组
        List<String> value = new ArrayList();
//        1.4根据key去redis里获取用户收藏的攻略数组，判断redis里是否存有数据
        if (stringRedisTemplate.hasKey(key)) {
//        1.5如果获取到了就将获取出来的json格式字符串解析回一个数组
            String valueStr = stringRedisTemplate.opsForValue().get(key);
            value = JSON.parseObject(valueStr, List.class);
        }

//        2.判断是否第一次点击收藏
        //获取vo对象
        StrategyStatisVO statisVo = this.getStatisVo(sid);
        if (value.contains(sid)) {
//        3.如果是第二次点击，收藏数减一，返回flase,将游记id从数组中移除
            statisVo.setFavornum(statisVo.getFavornum() - 1);
            value.remove(sid);
        } else {
//        4.如果是第一次点击收藏，收藏数加一，返回true,将游记id从数组中添加
            statisVo.setFavornum(statisVo.getFavornum() + 1);
            value.add(sid);
        }
        //        将key跟数组缓存到redis中，更新或保存
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(value));
        //更新vo数据
        this.setStatisVo(statisVo);
//        5.如果根据key无法获取到数组，就证明redis还没有缓存数据
        return value.contains(sid);
    }

    //点击回显
    @Override
    public List getFavor(String sid, String userId) {
//        1.2先创建key
        String key = RedisKeys.FAVOR.json(userId);
//        1.3创建一个空数组
        List<String> value = new ArrayList();
//        1.4根据key去redis里获取用户收藏的攻略数组，判断redis里是否存有数据
        if (stringRedisTemplate.hasKey(key)) {
//        1.5如果获取到了就将获取出来的json格式字符串解析回一个数组
            String valueStr = stringRedisTemplate.opsForValue().get(key);
            value = JSON.parseObject(valueStr, List.class);
        }
        return value;
    }

    //点赞
    @Override
    public boolean strategyThumbup(String sid, String id) {
//        1.根据用户id跟攻略id使用枚举创建key
        String key = RedisKeys.STRATEGYTHUMBUP.json(sid, id);
//        2.然后根据key去redis缓存里获取数据 ，判断是否顶过了
        if (!stringRedisTemplate.hasKey(key)) {
//        3.如果没有数据，就证明没有顶过，就将key缓存到redis中，并且设置时间
            Date now = new Date();
            Date end = DateUtil.getEndDate(now);
//        3.1.时间用用一天里最后的时间减去当前时间。
            long time = DateUtil.getDateBetween(end, now);
            stringRedisTemplate.opsForValue().set(key, "1", time, TimeUnit.SECONDS);
//        4.并且根据客户id获取vo对象，将顶数加一
            StrategyStatisVO vo = this.getStatisVo(sid);
            vo.setThumbsupnum(vo.getThumbsupnum() + 1);
            this.setStatisVo(vo);
//        5.返回true
            return true;
        }else {
//        6.如果顶过了，直接返回false
            return false;
        }
    }

    @Override
    public boolean isVOExists(String id) {
        String key = RedisKeys.STATISVO.json(id);
        return stringRedisTemplate.hasKey(key);
    }

    @Override
    public List<StrategyStatisVO> listStrategyVoByPattern(String pattern) {

        //vo的key集合
        // keys strategy_statis_vo:*
        Set<String> keys =stringRedisTemplate .keys(pattern);

        List<StrategyStatisVO> list = new ArrayList<>();
        if(keys != null && keys.size() > 0){
            for (String voKey : keys) {
                String voStr = stringRedisTemplate.opsForValue().get(voKey);
                list.add(JSON.parseObject(voStr, StrategyStatisVO.class));
            }
        }
        return list;
    }
}
